//
//  VisitLimitVC.swift
//  swiftDemo
//
//  Created by yaqiang bi on 2017/4/1.
//  Copyright © 2017年 毕小强. All rights reserved.
//
//  访问控制

import UIKit

class VisitLimitVC: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        
        
        let publicClass = SomePublicClass()
        let internalClass = SomeInternalClass()
        let filePrivateClass = SomeFilePrivateClass()
        let privateClass = SomePrivateClass()
        
        let _ = publicClass.someInternaleProperty
        let _ = internalClass.someFilePrivateMethod()
        let _ = filePrivateClass.someFilePrivateMethod()
        let _ = privateClass.somePrivateMethpd()
        
        let trcaked = TrackedString(numberOfEidts: 1, value:"哈哈")
        print("\(trcaked.numberOfEidts)")
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

/*
 *       自己理解(并不准确):
 *       privaite不可以被外部源文件和函数体外部访问
 *       fileprivate不可以被外部源文件访问
 *       internal public open默认可以被外部源文件 外部函数访问
 **/


//MARK:访问级别
public class SomePublicClass{
    public var somePublicProperty = 0
    var someInternaleProperty = 0
    fileprivate func someFilePrivateMethod(){
    
    }
    private func somePrivateMethod(){
    
    }
}

class SomeInternalClass {
    var someInternalProperty = 0
    fileprivate func someFilePrivateMethod(){
    
    }
    private func somePrivateMethod(){
    
    }
}

fileprivate class SomeFilePrivateClass{
    fileprivate func someFilePrivateMethod()  {
        
    }
    private func somePrivateMethod(){
    
    }
}

private class SomePrivateClass{
    func somePrivateMethpd()  {
        
    }
}

/*
 *       函数内部形参 实参 返回值必须必函数的访问级别高
 *       元祖的访问级别是由最低的访问级别元素所决定
 **/
private func someFunction()->(SomeInternalClass,SomePrivateClass){
    return (SomeInternalClass(),SomePrivateClass())
}

/*
 *   枚举元素的访问级别由枚举决定,枚举元素不能单独定义访问级别
 */
enum CompassPoint {
    case North
    case South
    case East
    case West
}

/*
 *    嵌套类型的访问级别自动拥有被嵌套类型的访问级别
 *    被嵌套类型的访问级别为private,嵌套类型访问级别默认为private
 *    被嵌套类型访问级别为public,嵌套类型访问级别为internal,如果想要public访问级别需要手动添加
 */



/*
 *      子类的访问级别不能高于父类的访问级别
 *      可以通过重写改变方法的访问级别
 */
//WARN:貌似,private级别的不能通过重写改变访问权限？
open class AandB{
    public class A{
        fileprivate func someMethod(){
            
        }
    }
    internal class B:A{
        override public func someMethod(){
            
        }
    }
}

/*
 *      常量、变量、属性、下标不能拥有比他们类型访问级别更高的访问级别
 *      getter和setter的访问级别和它们所属类型的访问级别相同
 *      setter可以拥有比getter更低的访问级别
 */
struct TrackedString {
    private(set) var numberOfEidts = 0
    var value:String = "" {
        didSet{
            numberOfEidts += 1
        }
    }
}

/*
 *      必要构造器的访问级别必须必须和所属类型的访问级别相同
 *      构造器参数的访问级别不能低于构造器本身的访问级别
 */



